package cn.jetpiece.cloud.common.app.modular.message.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.jetpiece.cloud.common.api.message.AnnouncementSendApi;
import cn.jetpiece.cloud.common.api.message.model.params.CreateAnnouncementSendParam;
import cn.jetpiece.cloud.common.api.message.model.params.UpdateAnnouncementSendParam;
import cn.jetpiece.cloud.common.api.message.model.query.AnnouncementSendQuery;
import cn.jetpiece.cloud.common.api.message.model.result.AnnouncementSendResult;
import cn.jetpiece.cloud.common.api.message.constans.MessageConstant;
import cn.jetpiece.cloud.common.app.modular.message.entity.AnnouncementSend;
import cn.jetpiece.cloud.common.app.modular.message.service.IAnnouncementSendService;
import cn.jetpiece.cloud.common.app.modular.message.wrapper.AnnouncementSendWrapper;
import cn.jetpiece.cloud.common.app.modular.websocket.manager.WebSocket;
import cn.jetpiece.cloud.core.context.LoginUserContext;
import cn.jetpiece.cloud.core.page.PageFactory;
import cn.jetpiece.cloud.core.query.QueryGenerator;
import cn.jetpiece.cloud.core.util.HttpContext;
import cn.jetpiece.cloud.model.contants.WebsocketConst;
import cn.jetpiece.cloud.model.model.LoginUser;
import cn.jetpiece.cloud.model.page.PageResult;
import cn.jetpiece.cloud.model.response.Result;
import cn.jetpiece.cloud.starter.app.modular.base.controller.BaseController;
import cn.jetpiece.cloud.uc.auth.support.TenantContext;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;
import java.util.List;

/**
 * 用户通告阅读标记表
 *
 * @author jetpiece
 * @since 2022-11-16
 */
@Slf4j
@RestController
@RequiredArgsConstructor
public class AnnouncementSendController extends BaseController<AnnouncementSend, IAnnouncementSendService> implements AnnouncementSendApi {
    private final IAnnouncementSendService announcementSendService;
    private final WebSocket webSocket;

    @Override
    public Result<String> add(CreateAnnouncementSendParam param) {
        try {
            AnnouncementSend announcementSend = BeanUtil.toBean(param, AnnouncementSend.class);
            if (announcementSendService.save(announcementSend)) {
                return Result.OK("添加成功!");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Result.error("添加失败");
    }

    @Override
    public Result<String> update(UpdateAnnouncementSendParam param) {
        try {
            AnnouncementSend oldBean = announcementSendService.getById(param.getId());
            if (oldBean == null) {
                return Result.error("数据未找到!");
            }
            AnnouncementSend announcementSend = BeanUtil.toBean(param, AnnouncementSend.class);
            if (announcementSendService.updateById(announcementSend)) {
                return Result.OK("编辑成功!");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Result.error("编辑失败");
    }

    @Override
    public Result<String> delete(Long id) {
        try {
            if (announcementSendService.removeById(id)) {
                return Result.OK("删除成功!");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return Result.error("删除失败");
    }

    @Override
    public Result<String> deleteBatch(String ids) {
        try {
            List<Long> idList = Convert.toList(Long.class, ids.split(","));
            if (announcementSendService.removeByIds(idList)) {
                return Result.OK("批量删除成功!");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return Result.error("批量删除失败");
    }

    @Override
    public Result<AnnouncementSendResult> get(Long id) {
        try {
            AnnouncementSend announcementSend = announcementSendService.getById(id);
            if (announcementSend == null) {
                return Result.error("数据未找到!");
            }
            return Result.OK(BeanUtil.toBean(announcementSend, AnnouncementSendResult.class));
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return Result.error("获取数据失败！");
    }

    @Override
    public Result<PageResult<AnnouncementSendResult>> page(AnnouncementSendQuery query) {
        query.setUserId(LoginUserContext.getInstance().getUsername());
        AnnouncementSend announcementSend = BeanUtil.toBean(query, AnnouncementSend.class);
        QueryWrapper<AnnouncementSend> queryWrapper = QueryGenerator.initQueryWrapper(announcementSend, HttpContext.getRequestParameters());
        Page<AnnouncementSend> page = PageFactory.defaultPage();
        if (page.orders().isEmpty()) {
            page.addOrder(OrderItem.asc("read_flag"), OrderItem.desc("create_time"));
        }
        if (StrUtil.isNotBlank(query.getMsgCategory())) {
            queryWrapper.inSql("announcement_id", "select id from common_announcement where send_status = 1 AND del_flag = 0 AND msg_category = '" + query.getMsgCategory() + "'");
        }
        IPage<AnnouncementSend> pageList = announcementSendService.page(page, queryWrapper);
        return Result.OK(new AnnouncementSendWrapper(pageList).setWrapper(true).wrapPageResult());
    }

    @Override
    public Result<String> importExcel(MultipartHttpServletRequest request) {
        return super.importXls(request);
    }

    @Override
    public ModelAndView exportExcel(AnnouncementSendQuery query) {
        return super.exportXls(query, AnnouncementSendResult.class, "用户通告阅读标记表");
    }

    @Override
    public Result<String> readOne(@RequestParam(name = "announcementId", required = false) Long announcementId, @RequestParam(name = "announcementSendId", required = false) Long announcementSendId) {
        LoginUser loginUser = LoginUserContext.getInstance().getLoginUser();
        AnnouncementSend announcementSend;
        if (announcementSendId != null) {
            announcementSend = announcementSendService.getById(announcementSendId);
        } else if (announcementId != null) {
            LambdaQueryWrapper<AnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AnnouncementSend::getAnnouncementId, announcementId);
            queryWrapper.eq(AnnouncementSend::getUserId, loginUser.getUsername());
            queryWrapper.last("LIMIT 1");
            announcementSend = announcementSendService.getOne(queryWrapper);
        } else {
            return Result.error("数据未找到!");
        }
        if (announcementSend == null) {
            return Result.error("数据未找到!");
        }
        AnnouncementSend updatedAnnouncementSend = new AnnouncementSend();
        updatedAnnouncementSend.setId(announcementSend.getId());
        updatedAnnouncementSend.setReadFlag(MessageConstant.HAS_READ_FLAG);
        updatedAnnouncementSend.setReadTime(new Date());
        boolean result = announcementSendService.updateById(updatedAnnouncementSend);
        if (result) {
            JSONObject obj = new JSONObject();
            obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
            obj.put(WebsocketConst.MSG_TXT, "批量设置已读");
            webSocket.sendMessage(TenantContext.getTenant(), loginUser.getUsername(), obj);
            return Result.error("设置成功!");
        }
        return Result.error("设置失败!");
    }

    @Override
    public Result<String> readAll() {
        LoginUser loginUser = LoginUserContext.getInstance().getLoginUser();
        LambdaQueryWrapper<AnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AnnouncementSend::getUserId, loginUser.getUsername());
        queryWrapper.eq(AnnouncementSend::getReadFlag, MessageConstant.NO_READ_FLAG);
        List<AnnouncementSend> announcementSendList = announcementSendService.list(queryWrapper);
        if (announcementSendList.isEmpty()) {
            return Result.OK("没有未读消息!");
        }
        Date now = new Date();
        for (AnnouncementSend announcementSend : announcementSendList) {
            AnnouncementSend updatedAnnouncementSend = new AnnouncementSend();
            updatedAnnouncementSend.setId(announcementSend.getId());
            updatedAnnouncementSend.setReadFlag(MessageConstant.HAS_READ_FLAG);
            updatedAnnouncementSend.setReadTime(now);
            announcementSendService.updateById(updatedAnnouncementSend);
        }
        JSONObject obj = new JSONObject();
        obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
        obj.put(WebsocketConst.MSG_TXT, "批量设置已读");
        webSocket.sendMessage(TenantContext.getTenant(), loginUser.getUsername(), obj);
        return Result.OK("操作成功!");
    }

}
